package dubbo.learn.core.beanfactorypostprocessor;

import dubbo.learn.registry.redis.RedisRegistry;
import dubbo.learn.core.config.parser.RegistryBeanDefinitionParser;
import dubbo.learn.core.util.BeanDefinitionRegistryUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * 服务提供者/服务消费者使用。
 *
 * 因为在使用redis 作为注册中心时，redis地址实际通过如下这个元素来配置：
 * <dubbo:registry address="redis://192.168.1.4:6379"/>
 *
 * 但是我们使用了redisson来作为redis客户端，所以需要引入redisson相关的bean，目前是通过直接读取
 * 类路径下的redisson.xml的方式来引入的，那么，此时redisson.xml里面配置的redis url地址就没办法使用
 * <dubbo:registry></dubbo:registry>里面的地址
 *
 * 所以，这里去修改redisson.xml中配置的地址为<dubbo:registry>中的地址
 */
@Slf4j
public class RedissonConfigBeanDefinitionPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition redissonClientbeanDefinition = BeanDefinitionRegistryUtil.getSingleBeanDefinition(beanFactory, RedissonClient.class);
        if (redissonClientbeanDefinition == null) {
            return;
        }

        String[] dependsOn = redissonClientbeanDefinition.getDependsOn();
        if (dependsOn == null || dependsOn.length == 0) {
            return;
        }

        String configBeanName = dependsOn[0];
        BeanDefinition redissonConfigBeanDefinition = beanFactory.getBeanDefinition(configBeanName);
        MutablePropertyValues propertyValues = redissonConfigBeanDefinition.getPropertyValues();
        PropertyValue propertyValue = propertyValues.getPropertyValue("address");

        // 获取redisRegistry中配置的值
        BeanDefinition redisRegistrybeanDefinition = BeanDefinitionRegistryUtil.getSingleBeanDefinition(beanFactory, RedisRegistry.class);
        PropertyValue addressConfigFromRedisRegistry = redisRegistrybeanDefinition.getPropertyValues().getPropertyValue(RegistryBeanDefinitionParser.ADDRESS);

        Object value = addressConfigFromRedisRegistry.getValue();
        log.info("change redisson url  value  to  {}",value);
        propertyValue.setConvertedValue(value);

    }
}
